using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BanZuiCloudControlAgent.Core.Mqtt.MessageCache;
using BanZuiCloudControlAgent.Core.Mqtt.Models;
using BanZuiCloudControlAgent.Utils.Common;
using BanZuiCloudControlAgent.Utils.Exceptions;
using BanZuiCloudControlAgent.Utils.Logging;

namespace BanZuiCloudControlAgent.Core.Mqtt.Sender
{
    /// <summary>
    /// 消息发送中间件，用于解耦业务代码与MQTT，提供统一的消息发送接口
    /// </summary>
    public class MessageSenderMiddleware
    {
        private readonly NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger();
        private readonly MqttMessageSender _mqttMessageSender;
        private readonly string _deviceCode;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="mqttMessageSender">MQTT消息发送器</param>
        /// <param name="deviceCode">设备编码</param>
        public MessageSenderMiddleware(MqttMessageSender mqttMessageSender, string deviceCode)
        {
            _mqttMessageSender = mqttMessageSender ?? throw new ArgumentNullException(nameof(mqttMessageSender));
            _deviceCode = deviceCode ?? throw new ArgumentNullException(nameof(deviceCode));
        }

        /// <summary>
        /// 发送任务状态上报消息，支持离线缓存
        /// </summary>
        /// <param name="taskId">任务ID</param>
        /// <param name="taskType">任务类型</param>
        /// <param name="status">任务状态</param>
        /// <param name="progress">任务进度</param>
        /// <param name="result">任务结果</param>
        /// <param name="errorMessage">错误消息</param>
        /// <returns>发送结果</returns>
        public async Task<bool> SendTaskReportAsync(string taskId, string taskType, int status, int progress, object result = null, string errorMessage = null)
        {
            try
            {
                TaskReportModel taskReport;
                Dictionary<string, object> data = null;
                
                // 如果result是Dictionary<string, object>类型，则直接使用
                if (result is Dictionary<string, object> dictResult)
                {
                    data = dictResult;
                }
                // 如果result不为空，则将其转换为字符串
                else if (result != null)
                {
                    data = new Dictionary<string, object> { { "result", result } };
                }
                
                // 根据状态选择合适的工厂方法创建任务上报消息
                switch (status)
                {
                    case 0: // 任务开始
                        taskReport = TaskReportModel.CreateTaskStartReport(_deviceCode, taskId, taskType);
                        break;
                    case 1: // 任务运行中
                        taskReport = TaskReportModel.CreateTaskProgressReport(_deviceCode, taskId, taskType, progress, 
                            result?.ToString() ?? "任务进行中", data);
                        break;
                    case 2: // 任务成功
                        taskReport = TaskReportModel.CreateTaskSuccessReport(_deviceCode, taskId, taskType, 
                            result?.ToString() ?? "任务完成", data);
                        break;
                    case 3: // 任务失败
                        taskReport = TaskReportModel.CreateTaskFailedReport(_deviceCode, taskId, taskType, 
                            errorMessage ?? "任务失败", data);
                        break;
                    case 4: // 任务暂停
                        taskReport = TaskReportModel.CreateTaskPauseReport(_deviceCode, taskId, taskType);
                        break;
                    default:
                        // 默认使用进度上报
                        taskReport = TaskReportModel.CreateTaskProgressReport(_deviceCode, taskId, taskType, progress, 
                            result?.ToString() ?? "任务状态更新", data);
                        break;
                }

                // 发送消息
                return await _mqttMessageSender.SendTaskReportAsync(taskReport);
            }
            catch (Exception ex)
            {
                _logger.Error($"发送任务状态上报消息失败: {ex.Message}", ex);
                return false;
            }
        }
        
        /// <summary>
        /// 发送任务开始上报消息
        /// </summary>
        /// <param name="taskId">任务ID</param>
        /// <param name="taskType">任务类型</param>
        /// <returns>发送结果</returns>
        public async Task<bool> SendTaskStartReportAsync(string taskId, string taskType)
        {
            var taskReport = TaskReportModel.CreateTaskStartReport(_deviceCode, taskId, taskType);
            return await _mqttMessageSender.SendTaskReportAsync(taskReport);
        }
        
        /// <summary>
        /// 发送任务进度上报消息
        /// </summary>
        /// <param name="taskId">任务ID</param>
        /// <param name="taskType">任务类型</param>
        /// <param name="progress">进度</param>
        /// <param name="message">进度描述</param>
        /// <param name="data">附加数据</param>
        /// <returns>发送结果</returns>
        public async Task<bool> SendTaskProgressReportAsync(string taskId, string taskType, int progress, string message = null, Dictionary<string, object> data = null)
        {
            var taskReport = TaskReportModel.CreateTaskProgressReport(_deviceCode, taskId, taskType, progress, message ?? "任务进行中", data);
            return await _mqttMessageSender.SendTaskReportAsync(taskReport);
        }
        
        /// <summary>
        /// 发送任务成功上报消息
        /// </summary>
        /// <param name="taskId">任务ID</param>
        /// <param name="taskType">任务类型</param>
        /// <param name="message">成功描述</param>
        /// <param name="data">附加数据</param>
        /// <returns>发送结果</returns>
        public async Task<bool> SendTaskSuccessReportAsync(string taskId, string taskType, string message = null, Dictionary<string, object> data = null)
        {
            var taskReport = TaskReportModel.CreateTaskSuccessReport(_deviceCode, taskId, taskType, message ?? "任务完成", data);
            return await _mqttMessageSender.SendTaskReportAsync(taskReport);
        }
        
        /// <summary>
        /// 发送任务失败上报消息
        /// </summary>
        /// <param name="taskId">任务ID</param>
        /// <param name="taskType">任务类型</param>
        /// <param name="errorMessage">错误信息</param>
        /// <param name="data">附加数据</param>
        /// <returns>发送结果</returns>
        public async Task<bool> SendTaskFailedReportAsync(string taskId, string taskType, string errorMessage, Dictionary<string, object> data = null)
        {
            var taskReport = TaskReportModel.CreateTaskFailedReport(_deviceCode, taskId, taskType, errorMessage, data);
            return await _mqttMessageSender.SendTaskReportAsync(taskReport);
        }
        
        /// <summary>
        /// 发送任务暂停上报消息
        /// </summary>
        /// <param name="taskId">任务ID</param>
        /// <param name="taskType">任务类型</param>
        /// <returns>发送结果</returns>
        public async Task<bool> SendTaskPauseReportAsync(string taskId, string taskType)
        {
            var taskReport = TaskReportModel.CreateTaskPauseReport(_deviceCode, taskId, taskType);
            return await _mqttMessageSender.SendTaskReportAsync(taskReport);
        }

        /// <summary>
        /// 发送错误上报消息，支持离线缓存
        /// </summary>
        /// <param name="errorType">错误类型</param>
        /// <param name="errorLevel">错误级别</param>
        /// <param name="errorCode">错误代码</param>
        /// <param name="errorMessage">错误消息</param>
        /// <param name="errorDetail">错误详情</param>
        /// <param name="taskId">任务ID</param>
        /// <param name="qqNumber">QQ号</param>
        /// <param name="context">上下文</param>
        /// <returns>发送结果</returns>
        public async Task<bool> SendErrorReportAsync(string errorType, int errorLevel, string errorCode, string errorMessage,
            string errorDetail = null, string taskId = null, string qqNumber = null, object context = null)
        {
            return await _mqttMessageSender.SendErrorReportAsync(errorType, errorLevel, errorCode, errorMessage, errorDetail, taskId, qqNumber, context);
        }

        /// <summary>
        /// 发送采集上报消息，支持离线缓存
        /// </summary>
        /// <param name="collectType">采集类型</param>
        /// <param name="qqNumber">QQ号</param>
        /// <param name="collectData">采集数据</param>
        /// <param name="collectTaskId">采集任务ID</param>
        /// <param name="batchNumber">批次号</param>
        /// <param name="totalBatches">总批次数</param>
        /// <param name="isLastBatch">是否为最后一批</param>
        /// <param name="totalCollected">总采集数量</param>
        /// <returns>发送结果</returns>
        public async Task<bool> SendCollectReportAsync(string collectType, string qqNumber, object collectData,
            string collectTaskId = null, int batchNumber = 0, int totalBatches = 1, bool isLastBatch = true, int totalCollected = 0)
        {
            return await _mqttMessageSender.SendCollectReportAsync(collectType, qqNumber, collectData, collectTaskId, batchNumber, totalBatches, isLastBatch, totalCollected);
        }

        /// <summary>
        /// 发送QQ在线列表上报消息，支持离线缓存
        /// </summary>
        /// <param name="onlineQQList">在线QQ列表</param>
        /// <returns>发送结果</returns>
        public async Task<bool> SendQQOnlineReportAsync(List<QQAccountInfoModel> onlineQQList)
        {
            return await _mqttMessageSender.SendQQOnlineReportAsync(onlineQQList);
        }

        /// <summary>
        /// 发送状态上报消息，不支持离线缓存
        /// </summary>
        /// <param name="isHeartbeat">是否为心跳消息</param>
        /// <param name="isFirstConnect">是否为首次连接</param>
        /// <returns>发送结果</returns>
        // public async Task<bool> SendStatusReportAsync(bool isHeartbeat = true, bool isFirstConnect = false)
        // {
        //     // 只有在MQTT已连接的情况下才发送状态上报消息
        //     if (_mqttMessageSender.IsConnected)
        //     {
        //         return await _mqttMessageSender.SendStatusReportAsync(isHeartbeat, isFirstConnect);
        //     }
        //     else
        //     {
        //         _logger.Debug($"MQTT未连接，跳过发送状态上报消息");
        //         return false;
        //     }
        // }

        /// <summary>
        /// 发送断开连接消息，不支持离线缓存
        /// </summary>
        /// <param name="reason">断开原因</param>
        /// <returns>发送结果</returns>
        public async Task<bool> SendDisconnectMessageAsync(string reason = "normal_disconnect")
        {
            // 只有在MQTT已连接的情况下才发送断开连接消息
            if (_mqttMessageSender.IsConnected)
            {
                return await _mqttMessageSender.SendDisconnectMessageAsync(reason);
            }
            else
            {
                _logger.Debug($"MQTT未连接，跳过发送断开连接消息");
                return false;
            }
        }
    }
} 